package com.dotflat.report.staff_checkin;

import com.dotflat.dashboard.service.DashboardService;
import com.dotflat.dashboard.vo.ChildrenCheckVO;
import com.dotflat.util.excelUtil.StringUtils;
import com.matt.commons.dto.sso.StaffDTO;
import com.matt.commons.model.StatusResponse;
import com.matt.commons.page.PagerQuery;
import com.matt.domain.record.CheckRecord;
import com.matt.foundation.model.ErrorCode;
import com.matt.foundation.model.MemVerificationCache;
import com.matt.foundation.utils.DateUtil;
import com.matt.foundation.utils.MapConvertUtil;
import com.matt.foundation.vo.ChildrenCheckRecordVo;
import com.matt.foundation.vo.ClassesCheckRecordVo;
import com.matt.repository.record.CheckRecordNativeRepository;
import com.matt.repository.record.CheckRecordRepository;
import com.matt.service.ChildrenService;
import com.matt.service.remoteCall.SsoCallService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

import static com.matt.foundation.constant.RequestConstant.TICKET;


@RestController
@RequestMapping("/v2/report/staff_checkin")
@Slf4j
@Api(tags = "报表 - 员工出勤")
public class StaffCheckinReportController {

    @Autowired
    CheckRecordRepository checkRecordRepository;

    @Autowired
    CheckRecordNativeRepository checkRecordNativeRepository;

    @Autowired
    private ChildrenService childrenService;

    @Autowired
    private SsoCallService ssoCallService;

    @Autowired
    protected MemVerificationCache cache;

    @Autowired
    protected DashboardService dashboardService;

    @ApiOperation(value = "获取指定日期员工的签到信息详情列表，按照员工分页")
    @GetMapping(value = "/list")
    public StatusResponse checkDateRecord(@RequestHeader(TICKET) String ticket,
                                          String staffId, String realName, String roleId, Integer status,
                                          Date beginDate, Date endDate,
                                          PagerQuery pagerQuery) {
        List<Map<String, Object>> content = null;
        if (StringUtils.isBlank(staffId)){
            Map pageMap = ssoCallService.getAreaStaffs(ticket, realName, roleId, status, pagerQuery);

            //这里是因为无法自动转PageImpl
            content = (List) pageMap.get("content");
            if (content == null || content.size() == 0) {
                StatusResponse.success(pageMap);
            }
        }else{
            StaffDTO staffDTO = ssoCallService.getStaffDTO(ticket, staffId);
            if (staffDTO == null){
                StatusResponse.error(ErrorCode.STAFF_NOT_EXIST, "指定ID员工不存在");
            }
            Map<String, Object> obj = MapConvertUtil.obejctToMap(staffDTO);
            content = new ArrayList<>();
            content.add(obj);
        }

        List<String> staffIds = content.stream().map(o->(String)o.get("id")).collect(Collectors.toList());

        Map<String, Map<String, Object>> cache = content.stream().collect(Collectors.toMap(o->o.get("id").toString(), o->o));

        List<ClassesCheckRecordVo> recordList = childrenService.findStaffCheckRecord(staffIds, beginDate, endDate );

        ClassesCheckRecordVo staffResult = recordList.get(0);

        //装配员工信息
        staffResult.setClassesName(String.format("员工出勤 （%s~%s）", DateUtil.dateToMd(beginDate), DateUtil.dateToMd(endDate)));

        List<ChildrenCheckRecordVo> list = staffResult.getChildrenList();

        list.stream().forEach(o->{
            Map<String, Object> staffMap = cache.get(o.getChildrenId());

            if (staffMap == null){
                return;
            }

//            private String realName;
//            private String headImgUrl;
//            private Integer gender;
            Object staffRealName = staffMap.get("realName");
            Object headImgUrl = staffMap.get("headImgUrl");
            Object gender = staffMap.get("gender");

            o.setChildrenName(staffRealName == null ? "" : (String) staffRealName);
            o.setImgUrl(headImgUrl == null ? "" : (String) headImgUrl);
            o.setGender(gender == null ? 0 : Integer.parseInt(gender.toString()));
        });



        return StatusResponse.success(recordList);
    }

    @GetMapping(value = "/staffCheckList")
    @ApiOperation(value = "获取指定日期所有员工的签到报表，日粒度,按照员工分页")
    public StatusResponse classCheckList( @RequestHeader(TICKET) String ticket,
                                          String staffId, String realName, String roleId, Integer status,
                                          Date beginDate, Date endDate,
                                          PagerQuery pagerQuery) {

        List<Map<String, Object>> staffPageContent = null;
        if (StringUtils.isBlank(staffId)){
            Map pageMap = ssoCallService.getAreaStaffs(ticket, realName, roleId, status, pagerQuery);

            //这里是因为无法自动转PageImpl
            staffPageContent = (List) pageMap.get("content");
            if (staffPageContent == null || staffPageContent.size() == 0) {
                StatusResponse.success(pageMap);
            }
        }else{
            StaffDTO staffDTO = ssoCallService.getStaffDTO(ticket, staffId);
            if (staffDTO == null){
                StatusResponse.error(ErrorCode.STAFF_NOT_EXIST, "指定ID员工不存在");
            }
            Map<String, Object> obj = MapConvertUtil.obejctToMap(staffDTO);
            staffPageContent = new ArrayList<>();
            staffPageContent.add(obj);
        }

        //翻页的staffId
        List<String> staffIds = staffPageContent.stream().map(o->(String)o.get("id")).collect(Collectors.toList());

        //学生考勤列表
        List<ChildrenCheckVO> childrenCheckList = dashboardService.getCheckRecordsByChildrenId(staffIds, beginDate,endDate);

        //按childrenId group
        Map<String, Map<String, ChildrenCheckVO>> checkListCache = new HashMap<>();
        childrenCheckList.stream().forEach(o->{
            Map<String, ChildrenCheckVO> childCheckCache = checkListCache.get(o.getChildrenId());
            if (childCheckCache == null){
                childCheckCache = new HashMap<>();
                checkListCache.put(o.getChildrenId(), childCheckCache);
            }
            childCheckCache.put(o.getCheckInTime(), o);
        });

        List<Map<String, Object>> mapList = new ArrayList<>();

        //所有天
        List<String> dateList = DateUtil.getDay(beginDate, endDate);

        for (int i = 0; i < staffPageContent.size(); i++) {
            Map<String, Object> staffMap = staffPageContent.get(i);

            String id = (String) staffMap.get("id");
            String name = (String) staffMap.get("realName");

            staffMap.put("name", name);

            //正常考勤
            int q1= 0;
            //请假考勤
            int q2= 0;
            //病假考勤
            int q3= 0;

            Map<String, ChildrenCheckVO> staffCheckCache = checkListCache.getOrDefault(id, new HashMap<>());
            for (int j = 0; j < dateList.size(); j++) {
                String dateStr = dateList.get(j);
                staffMap.put(dateStr, "");

                ChildrenCheckVO checkVO = staffCheckCache.get(dateStr);

                if (checkVO == null){
                    continue;
                }

                //出勤信息
                if (checkVO.getStatus() == 1 || checkVO.getStatus() == 2 ) {
                    staffMap.put(dateStr, "出勤");
                    q1++;
                }else if (checkVO.getStatus() == 4) {
                    if (checkVO.getHealthyStatus() != null && checkVO.getHealthyStatus() == 1) {
                        staffMap.put(dateStr, "病假");
                        q3++;
                    }else {
                        staffMap.put(dateStr, "请假");
                        q2++;
                    }
                }
            }
            //正常考勤统计
            staffMap.put("attendanceCount", q1);
            //请假考勤统计
            staffMap.put("sickCount", q2);
            //病假考勤统计
            staffMap.put("leaveCount", q3);
            mapList.add(staffMap);
        }
        return StatusResponse.success(mapList);
    }

    @RequestMapping(value = "/monthRecords", method = RequestMethod.GET)
    @ApiOperation(value = "月签到列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "month", value = "查询的月份，如 2019/06"),
            @ApiImplicitParam(name = "staffId", value = "员工id, 缺省为当前用户id")
    })
    public StatusResponse getMonthRecords(@RequestHeader(TICKET) String ticket, HttpServletRequest req, HttpServletResponse resp, String month, String staffId){

        StaffDTO staffDTO = null;

        if(StringUtils.isEmpty(staffId)) {
            staffDTO = cache.getStaff(ticket);
            staffId = staffDTO.getId();
        }else {
            staffDTO = ssoCallService.getStaffDTO(ticket, staffId);
        }

        List<ChildrenCheckRecordVo> items = checkRecordNativeRepository.findMonthRecordByChildrenId(staffId, month);

        if (items.size() > 0){
            StaffDTO finalStaffDTO = staffDTO;
            items.stream().forEach(o->{
                o.setChildrenName(finalStaffDTO.getRealName());
                o.setImgUrl(finalStaffDTO.getHeadImgUrl());
                o.setGender(finalStaffDTO.getGender());
            });
        }

        return StatusResponse.success(items);
    }


    @RequestMapping(value = "/dailyRecords", method = RequestMethod.GET)
    @ApiOperation(value = "当天签到详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "day", value = "查询的日期，如 2019/06/01"),
            @ApiImplicitParam(name = "staffId", value = "员工id, 缺省为当前用户id")
    })
    public StatusResponse getDailyReport(HttpServletRequest req, HttpServletResponse resp,
                                         @RequestHeader(TICKET) String ticket,
                                         String day, String staffId){
        StaffDTO staffDTO = null;

        if(StringUtils.isEmpty(staffId)) {
            staffDTO = cache.getStaff(ticket);
            staffId = staffDTO.getId();
        }else {
            staffDTO = ssoCallService.getStaffDTO(ticket, staffId);
        }

        List<CheckRecord> items = checkRecordRepository.findDayRecordByChildrenId(staffId, day);

        return StatusResponse.success(items);
    }

}
